home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / Macintosh Sample Code / SC.020.Transformer / UTransformer.inc1.p < prev    next >
Encoding:
Text File  |  1989-09-30  |  13.6 KB  |  519 lines  |  [TEXT/MPS ]

  1. {[j=20/57/1$]}
  2. {[f-]}
  3. {------------------------------------------------------------------------------
  4. #
  5. #    Apple Macintosh Developer Technical Support
  6. #
  7. #    BitMap Transformer
  8. #
  9. #    UTransformer.inc1.p -    Pascal Source
  10. #
  11. #    Copyright © 1989 Apple Computer, Inc.
  12. #    All rights reserved.
  13. #
  14. #    Versions:
  15. #                1.0                         10/89
  16. #
  17. #    Components:
  18. #                MTransformer.p                October 1, 1989
  19. #                UTransformer.p                October 1, 1989
  20. #                UTransformer.inc1.p         October 1, 1989
  21. #                Transformer.c                October 1, 1989
  22. #                Transformer.r                October 1, 1989
  23. #                Transformer.MAMake            October 1, 1989
  24. #                ProjInit                    October 1, 1989
  25. #                The BitMap Transmogrifier    October 1, 1989
  26. #
  27. #    Requirements:
  28. #                MacApp® 2.0ß9                July 10, 1989
  29. #
  30. # "Transformers" is a sample program that demonstrates how to translate,
  31. # rotate, and scale bitmaps. It uses a MacApp shell to open file, open
  32. # windows, and handle menus, but the core routine is written in vanilla C.
  33. #
  34. ------------------------------------------------------------------------------}
  35. {[f+]}
  36.  
  37. {--------------------------------------------------------------------------------------------------}
  38. { G L O B A L    V A R I A B L E S }
  39. {--------------------------------------------------------------------------------------------------}
  40.  
  41. VAR
  42.     gRotation           : INTEGER;
  43.     gCenter            : Point;
  44.     gDestination       : Point;
  45.     gScaleX            : Extended;
  46.     gScaleY            : Extended;
  47.  
  48. {--------------------------------------------------------------------------------------------------}
  49.     { E X T E R N A L    R O U T I N E S }
  50. {--------------------------------------------------------------------------------------------------}
  51.  
  52.     { From Transformer.c }
  53.  
  54. PROCEDURE GetThePicture(aRefNum: INTEGER; data: Ptr);
  55.     EXTERNAL;
  56.  
  57. PROCEDURE DoTransform(sourceBM, destBM: BitMap; center, destination: Point; rotation: INTEGER; Sx,
  58.                       Sy: Extended96);
  59.     EXTERNAL;
  60.  
  61. {--------------------------------------------------------------------------------------------------}
  62. { G L O B A L S }
  63. {--------------------------------------------------------------------------------------------------}
  64.  
  65. PROCEDURE ClearBitMap(aBitMap: BitMap);
  66.  
  67.     VAR
  68.         oldPort            : GrafPtr;
  69.         oldBits            : BitMap;
  70.         tempPort           : GrafPort;
  71.  
  72.     BEGIN
  73.         GetPort(oldPort);
  74.         OpenPort(@tempPort);
  75.         oldBits := tempPort.portBits;
  76.         SetPortBits(aBitMap);
  77.         WITH tempPort DO BEGIN
  78.             portRect := portBits.bounds;
  79.             ClipRect(portRect);
  80.             CopyRgn(clipRgn, visRgn);
  81.             EraseRect(portRect);
  82.         END;
  83.         SetPortBits(oldBits);
  84.         ClosePort(@tempPort);
  85.         SetPort(oldPort);
  86.     END;
  87.  
  88. {--------------------------------------------------------------------------------------------------}
  89. { T T r a n s f o r m e r A p p l i c a t i o n }
  90. {--------------------------------------------------------------------------------------------------}
  91.  
  92. PROCEDURE TTransformerApplication.ITransformerApplication(itsMainFileType: OSType);
  93.  
  94.     BEGIN
  95.         IApplication(itsMainFileType);
  96.  
  97.         RegisterStdType('TBitMapView', 'dflt');         { So my view will be substituted when
  98.                                                          MacApp® creates the "default view" }
  99.  
  100.         gRotation := 0;
  101.         gScaleX := 1;
  102.         gScaleY := 1;
  103.         gCenter := gZeroPt;
  104.         gDestination := gZeroPt;
  105.  
  106.         InitCursorCtl(NIL);                             { Use the cursor data in the resource fork }
  107.  
  108.         IF gDeadStripSuppression THEN BEGIN
  109.             IF Member(TObject(NIL), TBitMapView) THEN;
  110.             IF Member(TObject(NIL), TExtNumberText) THEN;
  111.         END;
  112.     END;
  113.  
  114. {--------------------------------------------------------------------------------------------------}
  115.  
  116. FUNCTION TTransformerApplication.AlreadyOpen(fileName: Str255;
  117.     volRefnum: INTEGER): TDocument; OVERRIDE;
  118.  
  119.     BEGIN
  120.         AlreadyOpen := NIL;
  121.     END;
  122.  
  123. {--------------------------------------------------------------------------------------------------}
  124.  
  125. FUNCTION TTransformerApplication.DoMakeDocument(itsCmdNumber: CmdNumber): TDocument;
  126.  
  127.     VAR
  128.         aDocument           : TBitMapDocument;
  129.  
  130.     BEGIN
  131.         { Allocate and initialize the document}
  132.         NEW(aDocument);
  133.         FailNIL(aDocument);
  134.  
  135.         aDocument.IBitMapDocument;
  136.         DoMakeDocument := aDocument;
  137.     END;
  138.  
  139. {--------------------------------------------------------------------------------------------------}
  140.  
  141. PROCEDURE TTransformerApplication.HandleFinderRequest; OVERRIDE;
  142.  
  143.     BEGIN
  144.         IF gFileCount > 0 THEN
  145.             INHERITED HandleFinderRequest;
  146.     END;
  147.  
  148. {--------------------------------------------------------------------------------------------------}
  149. { T B i t M a p D o c u m e n t }
  150. {--------------------------------------------------------------------------------------------------}
  151.  
  152. PROCEDURE TBitMapDocument.IBitMapDocument;
  153.  
  154.     VAR
  155.         fi                   : FailInfo;
  156.         data               : Ptr;
  157.         aBitMap            : BitMap;
  158.         oldPerm            : Boolean;
  159.         bmSize               : LONGINT;
  160.  
  161.     PROCEDURE HandleFailure(error: OSErr; message: LONGINT);
  162.  
  163.         BEGIN
  164.             Free;
  165.         END;
  166.  
  167.     BEGIN
  168.         fOrigBitMap.baseAddr := NIL;
  169.         IDocument(gMainFileType, kSignature, kUsesDataFork, NOT kUsesRsrcFork, NOT kDataOpen,
  170.                   NOT kRsrcOpen);
  171.  
  172.         WITH fOrigBitMap DO BEGIN
  173.             rowBytes := kRowBytes;
  174.             WITH bounds DO BEGIN
  175.                 top := 0;
  176.                 left := 0;
  177.                 bottom := kHeight;
  178.                 right := kWidth;
  179.                 bmSize := LONGINT(rowBytes) * bottom;
  180.             END;
  181.         END;
  182.  
  183.         CatchFailures(fi, HandleFailure);
  184.  
  185.         oldPerm := PermAllocation(TRUE);
  186.         data := NewPtrClear(bmSize);
  187.         oldPerm := PermAllocation(oldPerm);
  188.         FailNIL(data);
  189.         fOrigBitMap.baseAddr := data;
  190.  
  191.         Success(fi);
  192.     END;
  193.  
  194. {--------------------------------------------------------------------------------------------------}
  195.  
  196. PROCEDURE TBitMapDocument.Free; OVERRIDE;
  197.  
  198.     BEGIN
  199.         DisposIfPtr(fOrigBitMap.baseAddr);
  200.         INHERITED Free;
  201.     END;
  202.  
  203. {--------------------------------------------------------------------------------------------------}
  204.  
  205. PROCEDURE TBitMapDocument.CopyOrigBits(aBitMap: BitMap);
  206.  
  207.     VAR
  208.         sourceBitMap       : BitMap;
  209.  
  210.     BEGIN
  211.         sourceBitMap := fOrigBitMap;
  212.         CopyBits(sourceBitMap, aBitMap, sourceBitMap.bounds, sourceBitMap.bounds, srcCopy, NIL);
  213.     END;
  214.  
  215. {--------------------------------------------------------------------------------------------------}
  216.  
  217. PROCEDURE TBitMapDocument.DoRead(aRefNum: INTEGER; rsrcExists, forPrinting: Boolean); OVERRIDE;
  218.  
  219.     BEGIN
  220.         GetThePicture(aRefNum, fOrigBitMap.baseAddr);
  221.     END;
  222.  
  223. {--------------------------------------------------------------------------------------------------}
  224.  
  225. PROCEDURE TBitMapDocument.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  226.                                                      fieldType: INTEGER)); OVERRIDE;
  227.  
  228.     BEGIN
  229.         DoToField('TBitMapDocument', NIL, bClass);
  230.         DoToField('fOrigBitMap', NIL, bTitle);
  231.         DoToField('  baseAddr', @fOrigBitMap.baseAddr, bPointer);
  232.         DoToField('  rowBytes', @fOrigBitMap.rowBytes, bInteger);
  233.         DoToField('  bounds', @fOrigBitMap.bounds, bRect);
  234.  
  235.         INHERITED Fields(DoToField);
  236.     END;
  237.  
  238. {--------------------------------------------------------------------------------------------------}
  239.  
  240. PROCEDURE TBitMapDocument.GetOrigBitMap(VAR aBitMap: BitMap);
  241.  
  242.     BEGIN
  243.         aBitMap := fOrigBitMap;
  244.     END;
  245.  
  246. {--------------------------------------------------------------------------------------------------}
  247. { T B i t M a p V i e w }
  248. {--------------------------------------------------------------------------------------------------}
  249.  
  250. PROCEDURE TBitMapView.IRes(itsDocument: TDocument; itsSuperview: TView;
  251.     VAR itsParams: Ptr); OVERRIDE;
  252.  
  253.     VAR
  254.         fi                   : FailInfo;
  255.         data               : Ptr;
  256.         aBitMap            : BitMap;
  257.         oldPerm            : Boolean;
  258.         bmSize               : LONGINT;
  259.  
  260.     PROCEDURE HandleFailure(error: OSErr; message: LONGINT);
  261.  
  262.         BEGIN
  263.             Free;
  264.         END;
  265.  
  266.     BEGIN
  267.         fTransBitMap.baseAddr := NIL;
  268.         INHERITED IRes(itsDocument, itsSuperview, itsParams);
  269.  
  270.         WITH fTransBitMap DO BEGIN
  271.             rowBytes := kRowBytes;
  272.             WITH bounds DO BEGIN
  273.                 top := 0;
  274.                 left := 0;
  275.                 bottom := kHeight;
  276.                 right := kWidth;
  277.                 bmSize := LONGINT(rowBytes) * bottom;
  278.             END;
  279.         END;
  280.  
  281.         CatchFailures(fi, HandleFailure);
  282.  
  283.         oldPerm := PermAllocation(TRUE);
  284.         data := NewPtrClear(bmSize);
  285.         oldPerm := PermAllocation(oldPerm);
  286.         FailNIL(data);
  287.         fTransBitMap.baseAddr := data;
  288.  
  289.         Success(fi);
  290.  
  291.         aBitMap := fTransBitMap;
  292.         TBitMapDocument(fDocument).CopyOrigBits(aBitMap);
  293.     END;
  294.  
  295. {--------------------------------------------------------------------------------------------------}
  296.  
  297. PROCEDURE TBitMapView.Free; OVERRIDE;
  298.  
  299.     BEGIN
  300.         DisposIfPtr(fTransBitMap.baseAddr);
  301.         INHERITED Free;
  302.     END;
  303.  
  304. {--------------------------------------------------------------------------------------------------}
  305.  
  306. PROCEDURE TBitMapView.CallTransform(rotation: INTEGER; Sx, Sy: Extended);
  307.  
  308.     VAR
  309.         sourceBitMap       : BitMap;
  310.         destBitMap           : BitMap;
  311.         center               : Point;
  312.         destination        : Point;
  313.  
  314.     BEGIN
  315.         TBitMapDocument(fDocument).GetOrigBitMap(sourceBitMap);
  316.         destBitMap := fTransBitMap;
  317.  
  318.         WITH sourceBitMap.bounds DO BEGIN
  319.             center.h := right DIV 2;
  320.             center.v := bottom DIV 2;
  321.         END;
  322.  
  323.         WITH destBitMap.bounds DO BEGIN
  324.             destination.h := right DIV 2;
  325.             destination.v := bottom DIV 2;
  326.         END;
  327.  
  328.         DoTransform(sourceBitMap, destBitMap, center, destination, rotation, X80toX96(Sx),
  329.                     X80toX96(Sy));
  330.         ForceRedraw;
  331.     END;
  332.  
  333. {--------------------------------------------------------------------------------------------------}
  334.  
  335. FUNCTION TBitMapView.DoMenuCommand(aCmdNumber: CmdNumber): TCommand; OVERRIDE;
  336.  
  337.     VAR
  338.         aBitMap            : BitMap;
  339.         aWindow            : TWindow;
  340.         dismisser           : IDType;
  341.         sourceBitMap       : BitMap;
  342.         destBitMap           : BitMap;
  343.  
  344.     BEGIN
  345.         DoMenuCommand := gNoChanges;
  346.         CASE aCmdNumber OF
  347.             cNormal: BEGIN
  348.                 aBitMap := fTransBitMap;
  349.                 TBitMapDocument(fDocument).CopyOrigBits(aBitMap);
  350.                 ForceRedraw;
  351.             END;
  352.             cRot90: BEGIN
  353.                 CallTransform(90, 1.0, 1.0);
  354.             END;
  355.             cRot45: BEGIN
  356.                 CallTransform(45, 1.0, 1.0);
  357.             END;
  358.             cScale2: BEGIN
  359.                 CallTransform(0, 2.0, 2.0);
  360.             END;
  361.             cScaleHalf: BEGIN
  362.                 CallTransform(0, 0.5, 0.5);
  363.             END;
  364.             cRot45ScaleHalf: BEGIN
  365.                 CallTransform(45, 0.5, 0.5);
  366.             END;
  367.             cCustom: BEGIN
  368.                 aWindow := NewTemplateWindow(kOptionsDialog, NIL);
  369.                 dismisser := TDialogView(aWindow.FindSubView('DLOG')).PoseModally;
  370.                 IF (dismisser = 'OKOK') THEN BEGIN
  371.                     WITH aWindow DO BEGIN
  372.                         gRotation := TNumberText(FindSubView('ndeg')).GetValue;
  373.                         WITH gCenter DO BEGIN
  374.                             h := TNumberText(FindSubView('ncrx')).GetValue;
  375.                             v := TNumberText(FindSubView('ncry')).GetValue;
  376.                         END;
  377.                         WITH gDestination DO BEGIN
  378.                             h := TNumberText(FindSubView('ntrx')).GetValue;
  379.                             v := TNumberText(FindSubView('ntry')).GetValue;
  380.                         END;
  381.                         gScaleX := TExtNumberText(FindSubView('nscx')).GetExtValue;
  382.                         gScaleY := TExtNumberText(FindSubView('nscy')).GetExtValue;
  383.                         Close;
  384.                     END;
  385.  
  386.                     IF Focus THEN;
  387.                     BeginUpdate(thePort);                {Use thePort because we know we're focused}
  388.                     EraseRect(thePort^.portRect);
  389.                     DrawContents;
  390.                     EndUpdate(thePort);
  391.  
  392.                     TBitMapDocument(fDocument).GetOrigBitMap(sourceBitMap);
  393.                     destBitMap := fTransBitMap;
  394.  
  395.                     {$IFC qDebug}
  396.                     WrLblPt('gCenter', gCenter); Writeln;
  397.                     WrLblPt('gDestination', gDestination); Writeln;
  398.                     Writeln('gRotation = ', gRotation: 1);
  399.                     Writeln('gScaleX = ', gScaleX: 1);
  400.                     Writeln('gScaleY = ', gScaleY: 1);
  401.                     {$ENDC}
  402.  
  403.                     DoTransform(sourceBitMap, destBitMap, gCenter, gDestination, gRotation,
  404.                                 X80toX96(gScaleX), X80toX96(gScaleY));
  405.                     ForceRedraw;
  406.                 END
  407.                 ELSE BEGIN
  408.                     aWindow.Close;
  409.                 END;
  410.             END;
  411.             OTHERWISE DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  412.         END;
  413.     END;
  414.  
  415. {--------------------------------------------------------------------------------------------------}
  416.  
  417. PROCEDURE TBitMapView.DoSetupMenus; OVERRIDE;
  418.  
  419.     BEGIN
  420.         INHERITED DoSetupMenus;
  421.  
  422.         Enable(cNormal, TRUE);
  423.         Enable(cRot90, TRUE);
  424.         Enable(cRot45, TRUE);
  425.         Enable(cScale2, TRUE);
  426.         Enable(cScaleHalf, TRUE);
  427.         Enable(cRot45ScaleHalf, TRUE);
  428.         Enable(cCustom, TRUE);
  429.     END;
  430.  
  431. {--------------------------------------------------------------------------------------------------}
  432.  
  433. PROCEDURE TBitMapView.Draw(area: Rect); OVERRIDE;
  434.  
  435.     VAR
  436.         aBitMap            : BitMap;
  437.  
  438.     BEGIN
  439.         aBitMap := fTransBitMap;
  440.         CopyBits(aBitMap, GetWindow.GetGrafPort^.portBits, area, area, srcCopy, NIL);
  441.     END;
  442.  
  443. {--------------------------------------------------------------------------------------------------}
  444.  
  445. PROCEDURE TBitMapView.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  446.                                                  fieldType: INTEGER)); OVERRIDE;
  447.  
  448.     BEGIN
  449.         DoToField('fTransBitMap', NIL, bTitle);
  450.         DoToField('  baseAddr', @fTransBitMap.baseAddr, bPointer);
  451.         DoToField('  rowBytes', @fTransBitMap.rowBytes, bInteger);
  452.         DoToField('  bounds', @fTransBitMap.bounds, bRect);
  453.  
  454.         INHERITED Fields(DoToField);
  455.     END;
  456.  
  457. {--------------------------------------------------------------------------------------------------}
  458. { T E x t N u m b e r T e x t }
  459. {--------------------------------------------------------------------------------------------------}
  460.  
  461. FUNCTION TExtNumberText.GetExtValue: Extended;
  462.  
  463.     VAR
  464.         aString            : Str255;
  465.  
  466.     BEGIN
  467.         GetText(aString);
  468.         GetExtValue := Str2Num(aString);
  469.     END;
  470.  
  471. {--------------------------------------------------------------------------------------------------}
  472.  
  473. PROCEDURE TExtNumberText.SetExtValue(ext: Extended; redraw: Boolean);
  474.  
  475.     VAR
  476.         aString            : DecStr;
  477.         form               : DecForm;
  478.  
  479.     BEGIN
  480.         WITH form DO BEGIN
  481.             style := FloatDecimal;
  482.             digits := 0;
  483.         END;
  484.         Num2Str(form, ext, aString);
  485.         SetText(aString, redraw);
  486.     END;
  487.  
  488. {--------------------------------------------------------------------------------------------------}
  489.  
  490. FUNCTION TExtNumberText.Validate: LONGINT; OVERRIDE;
  491.  
  492.     VAR
  493.         theString           : Str255;
  494.         decRec               : Decimal;
  495.         extValue           : Extended;
  496.         index               : INTEGER;
  497.         validPrefix        : Boolean;
  498.  
  499.     BEGIN
  500.         Validate := kValidValue;
  501.  
  502.         GetText(theString);
  503.         IF theString = '' THEN
  504.             theString := '0';
  505.  
  506.         index := 1;
  507.         Str2Dec(theString, index, decRec, validPrefix);
  508.         IF validPrefix & (index > Length(theString)) THEN BEGIN
  509.             extValue := Dec2Num(decRec);
  510.             IF extValue < fMinimum THEN
  511.                 Validate := kValueTooSmall
  512.             ELSE IF extValue > fMaximum THEN
  513.                 Validate := kValueTooLarge;
  514.         END
  515.         ELSE BEGIN
  516.             Validate := kNonNumericCharacters;
  517.         END;
  518.     END;
  519.